if (typeof(Jocalize) != 'function') {
    Jocalize = {};
}

Jocalize.VERSION = '0.01';

// known functions
Jocalize.kf = [ 'quant' ];

// Default dictionary is empty
Jocalize.dict = {};

// quantity, singular, plural, negative
Jocalize.quant = function(q) {
    var j = Jocalize,
	t = arguments[1].split(',');
    var s = t[0],
	p = t[1],
	n = t[2];
    // The following rules are adapted from the man page of
    // Locale::Maketext
    var m = ((q == null || q == 0) && n != null) ? n :
	((q == null || q == 0) && n == null) ? '0' + ' ' + s :
	q == 1 ? '1' + ' ' + s : 
	p != null ? q + ' ' + p :
	q + ' ' + s + 's';
    return j.dict.msg[m] || m;
};

Jocalize.localize = function(msg) {
    var i,
	j = Jocalize;
    // Find l10n template. If there is no translation, then use
    // 'msg' itself.
    var	lt = (j.dict.msg[msg] || msg),
	// array of source patterns
	sp_arr = [
	    "\\[_\\d+?]"
	];
    for (i = 0; i < j.kf.length; ++i) {
	sp_arr.unshift("\\[" + j.kf[i] + ",_\\d+.*?\\]");
    }
    // Check if there is any customized l10n functions defined in
    // dictionary file.
    if (j.dict && j.dict.func) {
	for (i = 0; i < j.dict.func.length; ++i) {
	    sp_arr.unshift("\\[" + j.kf[i] + ",_\\d+.*?\\]");
	}
    }
    // source pattern
    var sp = sp_arr.join('|');
    var p = new RegExp('(' + 
		       [ '~~', '~\\[', '~\\]', sp, '.+?' ].join('|') +
		       ')', "g"); // pattern
    var r = lt.match(p);			     // result
    if (r == null) {
	return lt;
    }
    var p2 = new RegExp("(" + sp + ")");	     // pattern 2
    var r2,					     // result 2
	m = [],					     // message mapping
	c = [],					     // characters
	s = '',			// localized string
	lf,			// l10n function
	// is an l10n function?
	ilf = function(s) {
	    var p = new RegExp("\\[(\\w+),_(\\d+)(,.*)\\]");
	    // return
	    //  1. function name
	    //  2. user's argument
	    //  3. translation arguments
	    var r = s.match(p);
	    if (r != null) {
		r[3] = r[3].substr(1);
		return [ r[1], r[2], r[3] ];
	    }
	    return null;
	};

    for (i = 0; i < r.length; ++i) {
	r2 = r[i].match(p2);
	if (r2 != null && r2[1] != null) {
	    lf = ilf(r2[1]);
	    // Code for translating messages
	    if (lf != null) {
		if (j.dict != null &&
		    j.dict.func != null &&
		    typeof j.dict.func[lf[0]] == 'function') {
		    m[r[i]] = j.dict.func[lf[0]](arguments[lf[1]], lf[2]);
		}
		else if (typeof j[lf[0]] == 'function') {
		    m[r[i]] = j[lf[0]](arguments[lf[1]], lf[2]);
		}
	    }
	    else {
		m[r[i]] = arguments[function(m) {
		    var p = new RegExp("\\[_(\\d+)\\]");
		    var r = m.match(p);
		    return r != null ? r[1] : null;
		}(r2[1])];
	    }
	}
	c.push(r[i]);
    }

    for (i = 0; i < c.length; ++i) {
	s += c[i].search(p2) != -1 ? m[c[i]] : c[i];
    } 
    return s;
};

_ = function() { return Jocalize.localize.apply(Jocalize, arguments); };

/*

=head1 NAME

Jocalize - A javscript L10N module

=head1 SYNOPSIS

  document.write(_("Hello, World"));

  document.write(_("Hello, [_1]"));

  document.write(_("[quant,_1,document was, documents were, no document was] matched.", 0));
  document.write(_("[quant,_1,document was, documents were, no document was] matched.", 1));
  document.write(_("[quant,_1,document was, documents were, no document was] matched.", 2));

=head1 AUTHOR

Yung-chung Lin (henearkrxern@gmail.com)

=head1 COPYRIGHT

Copyright Yung-chung Lin 2008. All rights reserved.

This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
General Public License for more details.

http://www.gnu.org/copyleft/lesser.txt

=cut

*/